﻿#pragma once
#include <windows.h>
#include <iostream>
#include <assert.h>
#include <thread>
#include <mutex>
#include <algorithm>
#include <unordered_map>
#include "ObjectPool.h"

class FREELIST
{
public:
	void Push(void* start, void* end = nullptr, size_t n = 1);
	void* Pop();
	void PopRange(void*& start, void*& end, size_t n);
	bool Empty();

	size_t& InitSize();
	size_t& Size();

private:
	void* _freelist = nullptr;
	size_t _initsize = 1; // 慢增长变量
	size_t _size = 0; // 链表中内存块的数量
};

class SizeIndex
{
public:
	static size_t Align(size_t bytes); // 返回对齐数
	
	static size_t Index(size_t bytes); // 返回桶的下标

	static size_t _Align(size_t bytes, size_t alignNum);

	static size_t _Index(size_t bytes, size_t shiftNum);

	static size_t maxBatch(size_t alignBytes);

	static size_t Bytes2Pages(size_t alignBytes);
};
 
// 整体控制在最多10%左右的内碎⽚浪费
// [1,128] 8byte对⻬ freelist[0,16)
// [128+1,1024] 16byte对⻬ freelist[16,72)
// [1024+1,81024] 128byte对⻬ freelist[72,128)
// [8*1024+1,641024] 1024byte对⻬ freelist[128,184)
// [64*1024+1,256*1024] 8*1024byte对⻬ freelist[184,208)

struct Span
{
	size_t _id = 0; // 位置编号
	size_t _pages = 0; // 页数量
	size_t _ObjSize = 0; // span被cc分割的单元大小

	Span* _prev = nullptr;
	Span* _next = nullptr;

	size_t _useCnt = 0;
	void* _freelist = nullptr;

	bool _IsUse = false; // 有没有被cc使用
};


class Spanlist
{
public:
	Spanlist();

	void Insert(Span* pos, Span* span);

	void Erase(Span* pos);

	Span* Begin();

	Span* End();

	std::mutex& Mtx();

	bool Empty();

	Span* PopFront();

	void PushFront(Span* span);

private:
	Span* _head; // 哨兵头节点
	std::mutex _mtx; // 桶锁
};


